#include "bsp_common_stm32f103.h"
#include "bsp_led_stm32f103.h"

static void Bsp_LedInitMember_(Bsp_TLedItem* item)
{
    item->is_on = False;
}

void Bsp_LedInit_(void)
{
    Bsp_TLedUnion* self = &g_bsp_led_union;
    Bsp_TLedItem* item;
    const Bsp_TLedCfg* cfg;

    for (Int32 i = 0; i < self->count; i++)
    {
        item = &self->items[i];
        cfg = item->cfg;

        /*复位gpio*/
        LL_GPIO_ResetOutputPin(cfg->port, cfg->pin);

        /// 设置默认电平
        if (cfg->default_level)
            LL_GPIO_SetOutputPin(cfg->port, cfg->pin);
        else
            LL_GPIO_ResetOutputPin(cfg->port, cfg->pin);

        /// 配置引脚为输出
        LL_GPIO_SetPinSpeed(cfg->port, cfg->pin, LL_GPIO_SPEED_FREQ_LOW);
        LL_GPIO_SetPinOutputType(cfg->port, cfg->pin, LL_GPIO_OUTPUT_PUSHPULL);
        LL_GPIO_SetPinMode(cfg->port, cfg->pin, LL_GPIO_MODE_OUTPUT);
    }
}

void Bsp_LedDone_(void)
{
    Bsp_LedClose_();
}

void Bsp_LedOpen_(void)
{
    Bsp_TLedUnion* self = &g_bsp_led_union;
    Bsp_TLedItem* item;
    const Bsp_TLedCfg* cfg;

    for (Int32 i = 0; i < self->count; i++)
    {
        item = &self->items[i];
        cfg = item->cfg;

        Bsp_LedInitMember_(item);

        /// 设置默认电平
        if (cfg->default_level)
            LL_GPIO_SetOutputPin(cfg->port, cfg->pin);
        else
            LL_GPIO_ResetOutputPin(cfg->port, cfg->pin);
    }
}

void Bsp_LedClose_(void)
{
    
}

Int32 Bsp_LedSetOn(Int32 id, Bool status)
{
    Int32 result;
    Bsp_TLedUnion* self = &g_bsp_led_union;
    Int32 index;

    BSP_GET_INDEX(index, id);
    if (index >= 0)
    {
        Bsp_TLedItem* item = &self->items[index];
        const Bsp_TLedCfg* cfg = item->cfg;

        if (item->is_on != status)
        {
            item->is_on = status;
            
            status = status ^ cfg->is_reverse;

            if (status)
                LL_GPIO_SetOutputPin(cfg->port, cfg->pin);
            else
                LL_GPIO_ResetOutputPin(cfg->port, cfg->pin);

        }

        result = Bsp_kErrorCodeSuccess;
    }
    else
        result = Bsp_kErrorCodeParam;

    return result;
}

Int32 Bsp_LedGetStatus(Int32 id, Bool* status)
{
    Int32 result;
    Bsp_TLedUnion* self = &g_bsp_led_union;
    Int32 index;

    BSP_GET_INDEX(index, id);
    if (index >= 0)
    {
        Bsp_TLedItem* item = &self->items[index];

        *status = item->is_on;

        result = Bsp_kErrorCodeSuccess;
    }
    else
        result = Bsp_kErrorCodeParam;

    return result;
}

